package com.pocket.insight.base.mql;

import com.pocket.insight.base.mql.detector.SqlConversion;
import com.pocket.insight.entity.Type;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

public class TypedVal implements Eval.Val {

    private String                 str;              // 字段名
    private String                 alias;            // 别名
    private EvalScope     scope;
    private Type.TypeName type;
    private Object        query;
    private List<String>           collection;
    private String                 baseTableAlias;

    public TypedVal() {
    }

    public TypedVal(Object query) {
        setQuery(query);
    }

    public TypedVal(Object query, Type.TypeName type) {
        setQuery(query);
        this.type = type;
    }

    public TypedVal(Object query, EvalScope scope, String alias) {
        setQuery(query);
        setScope(scope);
        this.alias = alias;
    }

    @Override
    public String getStr() {
        return this.str;
    }

    public TypedVal setStr(String str) {
        this.str = str;
        return this;
    }

    public EvalScope getScope() {
        return this.scope;
    }

    public TypedVal setScope(EvalScope scope) {
        this.scope = scope;
        return this;
    }

    public Type.TypeName getType() {
        return this.type;
    }

    public TypedVal setType(Type.TypeName type) {
        this.type = type;
        return this;
    }

    public String getAlias() {
        return this.alias;
    }

    public TypedVal setAlias(String alias) {
        this.alias = alias;
        return this;
    }


    public String toString() {
        String result = null;
        if (this.str != null) {
            result = getStr();
        } else if (this.query instanceof List) {
            result = "[" + (String) ((List) this.query).stream().map(e -> (e != null) ? e.toString() : "").collect(Collectors.joining(",")) + "]";
        } else if (this.query != null) {
            result = this.query.toString();
        }
        if (!CollectionUtils.isEmpty(this.collection)) {
            result = "collection: " + (String) this.collection.stream().collect(Collectors.joining(",")) + ";  query: " + result;
        }
        return result;
    }

    public List<String> getCollection() {
        return this.collection;
    }

    public TypedVal setCollection(List<String> collection) {
        this.collection = collection;
        return this;
    }

    public Object getQuery() {
        return (this.query == null) ? this.str : this.query;
    }

    public void setQuery(Object query) {
        if (query instanceof String) {
            this.str = (String) query;
        } else if (query instanceof TypedVal) {
            if (((TypedVal) query).getStr() != null) {
                this.str = ((TypedVal) query).getStr();
            } else {
                this.query = ((TypedVal) query).getQuery();
            }
            this.collection = ((TypedVal) query).getCollection();
        } else {
            this.query = query;
        }
    }

    public String getBaseTableAlias() {
        return this.baseTableAlias;
    }

    public TypedVal setBaseTableAlias(String baseTableAlias) {
        this.baseTableAlias = baseTableAlias;
        return this;
    }

    public enum EvalScope {
        constant,
        row,
        distinct,
        aggregate,
        window;
    }
}
